const express = require('express');
const router = express.Router();
const { createSuccessResponse } = require('../../middleware/responseHandler.js');
const COS = require('cos-nodejs-sdk-v5');
const STS = require('qcloud-cos-sts');

// ==================== COS配置项 ====================
// const COS_CONFIG = {
//     // 腾讯云COS配置
//     secretId: 'AKIDISZTEn8GBxiFeqpaBcr2Di17lGev00oR', // 请填写您的腾讯云SecretId
//     secretKey: 'Xt7BE9zd3G9sOho9JG0XtFZuibUwJVUG', // 请填写您的腾讯云SecretKey
//     bucket: 'csgf-1330302093', // 请填写您的存储桶名称
//     region: 'ap-shanghai', // 请填写您的存储桶地域，如：ap-shanghai
//     uin: '1330302093', // 请填写您的腾讯云账号UIN（从存储桶名称中提取）
// };
// 子账号配置
const COS_CONFIG = {
    // 腾讯云COS配置
    secretId: 'AKIDgCWcXEhx1ub5MRIvLZaNyM7lCQREoAID', // 请填写您的腾讯云SecretId
    secretKey: 'tcAWgePvDI9NPFwQhmdKn5VhfQzKRL1W', // 请填写您的腾讯云SecretKey
    bucket: 'csgf-1330302093', // 请填写您的存储桶名称
    region: 'ap-shanghai', // 请填写您的存储桶地域，如：ap-shanghai
    uin: '1330302093', // 请填写您的腾讯云账号UIN（从存储桶名称中提取）
};

// ==================== COS工具类 ====================
class COSHelper {
    constructor() {
        this.config = COS_CONFIG;
        this.cos = new COS({
            SecretId: this.config.secretId,
            SecretKey: this.config.secretKey
        });
    }

    /**
     * 验证临时密钥是否有效
     * @param {Object} credentials 临时密钥信息
     * @returns {Promise<boolean>} 返回密钥是否有效
     */
    async validateCredentials(credentials) {
        try {
            // 检查必要字段是否存在
            if (!credentials.TmpSecretId || !credentials.TmpSecretKey || !credentials.SecurityToken) {
                return false;
            }

            // 检查时间是否有效
            const now = Math.floor(Date.now() / 1000);
            if (credentials.ExpiredTime && now >= credentials.ExpiredTime) {
                return false;
            }

            return true;
        } catch (error) {
            return false;
        }
    }

    /**
     * 使用STS生成临时访问密钥
     * @param {string} operation 操作类型: upload/download/manage/view/full
     * @param {number} duration 有效期(秒)，默认3600秒
     * @returns {Promise<Object>} 返回临时秘钥信息
     */
    async generateTemporaryCredentials(operation = 'upload', duration = 3600) {
        try {
            // 生成权限策略
            const policy = this.generatePolicy(operation);

            // 使用STS生成临时密钥
            const credential = await new Promise((resolve, reject) => {
                STS.getCredential({
                    secretId: this.config.secretId,
                    secretKey: this.config.secretKey,
                    bucket: this.config.bucket,
                    region: this.config.region,
                    durationSeconds: duration,
                    policy: policy
                }, (err, credential) => {
                    if (err) {
                        reject(new Error(err.Message || err.message || 'STS调用失败'));
                    } else {
                        resolve(credential);
                    }
                });
            });

            // 安全地访问credential数据
            const credentials = credential.credentials || credential;
            const tmpSecretId = credentials.tmpSecretId || credentials.TmpSecretId;
            const tmpSecretKey = credentials.tmpSecretKey || credentials.TmpSecretKey;
            const sessionToken = credentials.sessionToken || credentials.SecurityToken;

            if (!tmpSecretId || !tmpSecretKey || !sessionToken) {
                throw new Error(`STS返回数据格式错误，缺少必要字段`);
            }

            const result = {
                // 临时密钥信息
                TmpSecretId: tmpSecretId,
                TmpSecretKey: tmpSecretKey,
                SecurityToken: sessionToken,

                // 时间信息
                StartTime: credential.startTime || Math.floor(Date.now() / 1000),
                ExpiredTime: credential.expiredTime || (Math.floor(Date.now() / 1000) + duration),
                DurationSeconds: duration,

                // 配置信息
                Bucket: this.config.bucket,
                Region: this.config.region,

                // 权限信息
                Operation: operation,
                Policy: policy,

                // 请求信息
                RequestId: this.generateRequestId(),
            };

            // 验证临时密钥有效性
            const isValid = await this.validateCredentials(result);
            if (!isValid) {
                throw new Error('临时密钥验证失败，密钥无效');
            }

            return result;
        } catch (error) {
            throw new Error(`生成临时凭证失败: ${error.message}`);
        }
    }

    /**
     * 获取允许的操作列表
     * @param {string} operation 操作类型
     * @returns {Array} 允许的操作列表
     */
    getAllowActions(operation) {
        const actionMap = {
            upload: [
                // 基础上传权限
                'name/cos:PutObject',                    // 简单上传 - 适用于小文件
                'name/cos:PostObject',                   // 表单上传 - 适用于表单提交

                // 分片上传核心权限
                'name/cos:InitiateMultipartUpload',      // 初始化分片上传 - 创建分片上传任务
                'name/cos:UploadPart',                   // 上传分片 - 上传单个分片数据
                'name/cos:CompleteMultipartUpload',      // 完成分片上传 - 合并所有分片
                'name/cos:AbortMultipartUpload',         // 中止分片上传 - 取消分片上传任务

                // 分片上传辅助权限
                'name/cos:ListMultipartUploads',         // 列出分片上传任务 - 查询进行中的分片上传
                'name/cos:ListParts',                    // 列出已上传分片 - 查询已上传的分片列表

                // 对象访问权限（用于分片上传过程中的验证）
                'name/cos:HeadObject',                   // 获取对象元数据 - 检查文件是否存在
                'name/cos:GetObject',                    // 获取对象内容 - 用于断点续传验证

                // 存储桶访问权限（用于分片上传过程中的验证）
                'name/cos:GetBucketLocation',            // 获取存储桶位置 - 确定存储桶地域
                'name/cos:ListBucket'                    // 列出存储桶内容 - 验证存储桶访问权限
            ],
            download: [
                // 文件下载权限
                'name/cos:GetObject',                     // 获取对象内容 - 下载文件
                'name/cos:HeadObject'                     // 获取对象元数据 - 获取文件信息（大小、类型等）
            ],
            view: [
                // 文件查看权限
                'name/cos:GetObject',                     // 获取对象内容 - 下载/查看文件
                'name/cos:HeadObject',                    // 获取对象元数据 - 获取文件信息

                // 存储桶查看权限
                'name/cos:ListBucket',                    // 列出存储桶内容 - 查看文件列表
                'name/cos:GetBucketLocation',             // 获取存储桶位置 - 确定存储桶地域

                // 对象访问控制权限
                'name/cos:GetObjectAcl',                  // 获取对象访问控制列表 - 查看文件权限设置
                'name/cos:GetBucketAcl'                   // 获取存储桶访问控制列表 - 查看存储桶权限设置
            ],
            manage: [
                // 文件删除权限
                'name/cos:DeleteObject',                  // 删除单个对象 - 删除文件
                'name/cos:DeleteMultipleObjects',         // 批量删除对象 - 批量删除文件

                // 文件复制权限
                'name/cos:PutObjectCopy',                 // 复制对象 - 复制文件到新位置

                // 访问控制权限
                'name/cos:PutObjectAcl',                  // 设置对象访问控制 - 设置文件权限
                'name/cos:GetObjectAcl',                  // 获取对象访问控制 - 查看文件权限

                // 存储桶管理权限
                'name/cos:PutBucketAcl',                  // 设置存储桶访问控制 - 设置存储桶权限
                'name/cos:GetBucketAcl'                   // 获取存储桶访问控制 - 查看存储桶权限
            ],
            full: [
                // 完整权限 - 包含所有COS操作权限
                'name/cos:*'                              // 通配符权限 - 允许所有COS操作
            ]
        };

        return actionMap[operation] || actionMap.upload;
    }

    /**
     * 生成权限策略
     * @param {string} operation 操作类型
     * @returns {Object} 权限策略
     */
    generatePolicy(operation) {
        const basePolicy = {
            version: '2.0',
            statement: [
                {
                    effect: 'allow',
                    action: this.getAllowActions(operation),
                    resource: [
                        // 存储桶级别的权限 - 使用实际的存储桶名称
                        `qcs::cos:${this.config.region}:uid/${this.config.uin}:${this.config.bucket}`,
                        // 对象级别的权限 - 使用实际的存储桶名称
                        `qcs::cos:${this.config.region}:uid/${this.config.uin}:${this.config.bucket}/uploads/*`
                    ]
                }
            ]
        };

        return basePolicy;
    }

    /**
     * 生成请求ID
     * @returns {string} 请求ID
     */
    generateRequestId() {
        return require('crypto').randomUUID();
    }

    /**
     * 获取上传专用临时秘钥
     * @param {number} duration 有效期(秒)
     * @returns {Promise<Object>} 返回上传SDK配置
     */
    async getUploadCredentials(duration = 3600) {
        return this.generateTemporaryCredentials('upload', duration);
    }

    /**
     * 获取下载专用临时秘钥
     * @param {number} duration 有效期(秒)
     * @returns {Promise<Object>} 返回下载SDK配置
     */
    async getDownloadCredentials(duration = 3600) {
        return this.generateTemporaryCredentials('download', duration);
    }

    /**
     * 获取查看专用临时秘钥（列表、详情等）
     * @param {number} duration 有效期(秒)
     * @returns {Promise<Object>} 返回查看SDK配置
     */
    async getViewCredentials(duration = 3600) {
        return this.generateTemporaryCredentials('view', duration);
    }

    /**
     * 获取管理专用临时秘钥（删除、移动等）
     * @param {number} duration 有效期(秒)
     * @returns {Promise<Object>} 返回管理SDK配置
     */
    async getManageCredentials(duration = 3600) {
        return this.generateTemporaryCredentials('manage', duration);
    }

    /**
     * 获取完整权限临时秘钥（所有操作）
     * @param {number} duration 有效期(秒)
     * @returns {Promise<Object>} 返回完整权限SDK配置
     */
    async getFullCredentials(duration = 3600) {
        return this.generateTemporaryCredentials('full', duration);
    }

    /**
     * 检查COS配置
     * @returns {Promise<boolean>} 返回配置是否有效
     */
    async checkConfig() {
        try {
            // 检查腾讯云配置
            if (!this.config.secretId || !this.config.secretKey) {
                return false;
            }

            // 检查必要配置
            if (!this.config.bucket || !this.config.region) {
                return false;
            }

            // 检查是否还是默认配置
            if (this.config.secretId === 'YOUR_SECRET_ID' ||
                this.config.secretKey === 'YOUR_SECRET_KEY' ||
                this.config.bucket === 'YOUR_BUCKET_NAME' ||
                this.config.region === 'YOUR_REGION' ||
                this.config.uin === 'YOUR_UIN') {
                return false;
            }

            return true;
        } catch (error) {
            return false;
        }
    }
}

// 创建COS工具实例
const cosHelper = new COSHelper();

// ==================== 路由定义 ====================

/**
 * 获取上传权限
 * @param {number} duration - 有效期(秒)，默认3600秒
 * @returns {Promise<object>} 返回上传权限配置
 */
router.post("/getUploadCredentials", (req, res, next) => {
    const { duration = 3600 } = req.body;

    // 参数验证
    if (duration < 300 || duration > 7200) {
        return res.status(200).json({
            success: false,
            code: 400,
            message: '有效期必须在300-7200秒之间',
            error: '有效期必须在300-7200秒之间',
            timestamp: Date.now()
        });
    }

    // 检查配置
    cosHelper.checkConfig().then(isValid => {
        if (!isValid) {
            return res.status(200).json({
                success: false,
                code: 500,
                message: 'COS配置无效，请检查配置项',
                error: 'COS配置无效，请检查配置项',
                timestamp: Date.now()
            });
        }

        // 获取上传权限
        return cosHelper.getUploadCredentials(duration);
    }).then(credentials => {
        res.json(createSuccessResponse(credentials, '获取上传权限成功'));
    }).catch(error => {
        console.error('获取上传权限错误:', error);
        next(error);
    });
});

/**
 * 获取下载权限
 * @param {number} duration - 有效期(秒)，默认3600秒
 * @returns {Promise<object>} 返回下载权限配置
 */
router.post("/getDownloadCredentials", (req, res, next) => {
    const { duration = 3600 } = req.body;

    // 参数验证
    if (duration < 300 || duration > 7200) {
        return res.status(200).json({
            success: false,
            code: 400,
            message: '有效期必须在300-7200秒之间',
            error: '有效期必须在300-7200秒之间',
            timestamp: Date.now()
        });
    }

    // 检查配置
    cosHelper.checkConfig().then(isValid => {
        if (!isValid) {
            return res.status(200).json({
                success: false,
                code: 500,
                message: 'COS配置无效，请检查配置项',
                error: 'COS配置无效，请检查配置项',
                timestamp: Date.now()
            });
        }

        // 获取下载权限
        return cosHelper.getDownloadCredentials(duration);
    }).then(credentials => {
        res.json(createSuccessResponse(credentials, '获取下载权限成功'));
    }).catch(error => {
        console.error('获取下载权限错误:', error);
        next(error);
    });
});

/**
 * 获取查看权限
 * @param {number} duration - 有效期(秒)，默认3600秒
 * @returns {Promise<object>} 返回查看权限配置
 */
router.post("/getViewCredentials", (req, res, next) => {
    const { duration = 3600 } = req.body;

    // 参数验证
    if (duration < 300 || duration > 7200) {
        return res.status(200).json({
            success: false,
            code: 400,
            message: '有效期必须在300-7200秒之间',
            error: '有效期必须在300-7200秒之间',
            timestamp: Date.now()
        });
    }

    // 检查配置
    cosHelper.checkConfig().then(isValid => {
        if (!isValid) {
            return res.status(200).json({
                success: false,
                code: 500,
                message: 'COS配置无效，请检查配置项',
                error: 'COS配置无效，请检查配置项',
                timestamp: Date.now()
            });
        }

        // 获取查看权限
        return cosHelper.getViewCredentials(duration);
    }).then(credentials => {
        res.json(createSuccessResponse(credentials, '获取查看权限成功'));
    }).catch(error => {
        console.error('获取查看权限错误:', error);
        next(error);
    });
});

/**
 * 获取管理权限
 * @param {number} duration - 有效期(秒)，默认3600秒
 * @returns {Promise<object>} 返回管理权限配置
 */
router.post("/getManageCredentials", (req, res, next) => {
    const { duration = 3600 } = req.body;

    // 参数验证
    if (duration < 300 || duration > 7200) {
        return res.status(200).json({
            success: false,
            code: 400,
            message: '有效期必须在300-7200秒之间',
            error: '有效期必须在300-7200秒之间',
            timestamp: Date.now()
        });
    }

    // 检查配置
    cosHelper.checkConfig().then(isValid => {
        if (!isValid) {
            return res.status(200).json({
                success: false,
                code: 500,
                message: 'COS配置无效，请检查配置项',
                error: 'COS配置无效，请检查配置项',
                timestamp: Date.now()
            });
        }

        // 获取管理权限
        return cosHelper.getManageCredentials(duration);
    }).then(credentials => {
        res.json(createSuccessResponse(credentials, '获取管理权限成功'));
    }).catch(error => {
        console.error('获取管理权限错误:', error);
        next(error);
    });
});

/**
 * 获取完整权限
 * @param {number} duration - 有效期(秒)，默认3600秒
 * @returns {Promise<object>} 返回完整权限配置
 */
router.post("/getFullCredentials", (req, res, next) => {
    const { duration = 3600 } = req.body;

    // 参数验证
    if (duration < 300 || duration > 7200) {
        return res.status(200).json({
            success: false,
            code: 400,
            message: '有效期必须在300-7200秒之间',
            error: '有效期必须在300-7200秒之间',
            timestamp: Date.now()
        });
    }

    // 检查配置
    cosHelper.checkConfig().then(isValid => {
        if (!isValid) {
            return res.status(200).json({
                success: false,
                code: 500,
                message: 'COS配置无效，请检查配置项',
                error: 'COS配置无效，请检查配置项',
                timestamp: Date.now()
            });
        }

        // 获取完整权限
        return cosHelper.getFullCredentials(duration);
    }).then(credentials => {
        res.json(createSuccessResponse(credentials, '获取完整权限成功'));
    }).catch(error => {
        console.error('获取完整权限错误:', error);
        next(error);
    });
});

module.exports = router;